# -*- coding: utf-8 -*-
import cgi
import datetime
import wsgiref.handlers

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp

import decorator as dc

import models.shippingOrder as som
import models.milestonePlan as mpm
import models.trackingInfo as tim
import models.status as sm
import models.user as um

import views.Stats as sv

import datetime

class StatsContr( webapp.RequestHandler ):

    def changeTimeLinks(self, action):
      times = [ 
      ['all', 'all time'],
      ['lastyear', 'last year'],
      ['lastmonth', 'last month'],
      ['lastweek', 'last week'],
      ['lastday', 'last day'] ]

      response = '<table cellpadding="7" cellspacing="0"><tr>\n'
      response += '<td><b>Change time:</b></td>'
      for time in times:
        response += '<td><center><a href="/stats/%s/%s">%s</a></td>\n' % (action, time[0], time[1])
      response += '</tr></table>\n\n'
      return response

    @dc.decorate
    def get(self, action, *params, **kwds):

        if um.UserModel.userRole() != 'manager' and um.UserModel.userRole() != 'admin':
           self.response.out.write("<font color=\"red\"><b>You have no rights to do this action.</b></font>")

        time = params[0]

        if time == 'all':
            timeFilter = 0
            pointDiff = '%Y'
            pointShow = '%Y'
            pointOffset = -2009
            strings = ['all time', 'year']
            points = []
            for i in range(2009, datetime.date.today().year+1):
                points.append(['',[]])

        elif time == 'lastyear':
            timeFilter = (datetime.date.today() - datetime.timedelta(days=365))
            pointDiff = '%m'
            pointShow = '%m/%Y'
            pointOffset = -1
            strings = ['last year', 'month']
            points = []
            for i in range(0,12):
                points.append(['',[]])
        elif time == 'lastmonth':
            timeFilter = (datetime.date.today() - datetime.timedelta(days=30))
            pointDiff = '%d'
            pointShow = '%b %d'
            pointOffset = -int(datetime.date.today().strftime('%d'))
            points = []
            strings = ['last month', 'day']
            for i in range(0,31):
                points.append(['',[]])
        elif time == 'lastweek':
            timeFilter = (datetime.date.today() - datetime.timedelta(days=7))
            pointDiff = '%d'
            pointShow = '%b %d'
            pointOffset = -int(datetime.date.today().strftime('%d'))
            points = []
            strings = ['last week', 'day']
            for i in range(0,7):
                points.append(['',[]])
        elif time == 'lastday':
            timeFilter = (datetime.date.today() - datetime.timedelta(days=1))
            pointDiff = '%H'
            pointShow = '%H:00'
            pointOffset = 0 
            points = []
            strings = ['last day', 'hour']
            for i in range(0,24):
                points.append(['',[]])
      
        if action == 'averMPDelay':
            lastPoint = ''
            query = db.Query(som.SOModel)
            query.filter('startTime >=', timeFilter)
            query.order('startTime')

            sum = -1
            n = -1
            for so in query:
                curPoint = so.startTime.strftime(pointDiff)
                if lastPoint != curPoint:
                    if n != -1:
                        if n == 0:
                            avg = 0
                        else:
                            avg = sum/n
                        idx = int(lastPoint)+pointOffset
                        if idx >= 0:
                            points[idx] = [lastShow, [avg]]
                    sum = 0
                    n = 0
                    lastPoint = curPoint
                    lastShow = so.startTime.strftime(pointShow)

                mp = mpm.MPModel.queryLatest(mpm.MPModel, so.mp)
               
                if mp.count() == 0:
                    continue 
                sum += mp[0].currentDelay
                n   += 1

            if n != -1:
                if n == 0:
                    avg = 0
                else:
                    avg = sum/n
                idx = int(lastPoint)+pointOffset
                if idx >= 0:
                    points[idx] = [lastShow, [avg]]
            self.response.out.write( sv.showAverMPDelay( points  , strings ) )

        elif action == 'delayDist':
            lastPoint = ''
            default_point = [0,0,0,0,0] # 0, 1-2, 3-5, 5-10, 10+
            query = db.Query(som.SOModel)
            query.filter('startTime >=', timeFilter)
            query.order('startTime')

            point = []
            for so in query:
                curPoint = so.startTime.strftime(pointDiff)
                if lastPoint != curPoint:
                    if point != []:
                        idx = int(lastPoint)+pointOffset
                        if idx >= 0:
                            points[idx] = [lastShow, point]
                    point = default_point[:]
                    lastPoint = curPoint
                    lastShow = so.startTime.strftime(pointShow)

                mp = mpm.MPModel.queryLatest(mpm.MPModel, so.mp)
               
                if mp.count() == 0:
                    continue 
                d = mp[0].currentDelay
                if d == 0:
                    i = 0
                elif d <= 2:
                    i = 1
                elif d <= 5:
                    i = 2
                elif d <= 10:
                    i = 3
                else:
                    i = 4

                point[i] += 1

            if point != []:
                idx = int(lastPoint)+pointOffset
                if idx >= 0:
                    points[idx] = [lastShow, point]
            self.response.out.write( sv.showDelayDist( points  , strings ) )
        elif action == 'statDist':
            lastPoint = ''

            # tak naprawde to powinno byc stati, nie statuses :P
            statuses = []
            statuses_r = {}
            default_point = []
            query = sm.StatusModel.all()
            i = 0
            for result in query:
                statuses.append(result.description)
                statuses_r[result.ident] = i
                default_point.append(0)
                i += 1

            query = db.Query(som.SOModel)
            query.filter('startTime >=', timeFilter)
            query.order('startTime')

            point = [] 
            for so in query:
                curPoint = so.startTime.strftime(pointDiff)
                if lastPoint != curPoint:
                    if point != []:
                        idx = int(lastPoint)+pointOffset
                        if idx >= 0:
                            points[idx] = [lastShow, point]
                    point = default_point[:]
                    lastPoint = curPoint
                    lastShow = so.startTime.strftime(pointShow)

                ti = tim.TIModel.all()
                ti.filter('shippingOrder =', so.ident)
                ti.filter('archival =', False)
                if ti.count() == 0:
                    continue
                
                point[statuses_r[ti[0].status]] += 1

            if point != []:
                idx = int(lastPoint)+pointOffset
                if idx >= 0:
                    points[idx] = [lastShow, point]
            self.response.out.write( sv.showStatDist( points, statuses, strings ) )
 
        elif action == 'succSO':
            lastPoint = ''

            # tak naprawde to powinno byc stati, nie statuses :P
            statuses = []
            statuses_r = {}
            query = sm.StatusModel.all()
            i = 0
            for result in query:
                statuses.append(result.description)
                statuses_r[result.ident] = result.isSuccess
                i += 1

            query = db.Query(som.SOModel)
            query.filter('startTime >=', timeFilter)
            query.order('startTime')

            point = [] 
            for so in query:
                curPoint = so.startTime.strftime(pointDiff)
                if lastPoint != curPoint:
                    if point != []:
                        idx = int(lastPoint)+pointOffset
                        if idx >= 0:
                            points[idx] = [lastShow, point]
                    point = [0,0]
                    lastPoint = curPoint
                    lastShow = so.startTime.strftime(pointShow)

                ti = tim.TIModel.all()
                ti.filter('shippingOrder =', so.ident)
                ti.filter('archival =', False)
                if ti.count() == 0:
                    continue
                
                if statuses_r[ti[0].status]:
                    point[0] += 1
                else:
                    point[1] += 1

            if point != []:
                idx = int(lastPoint)+pointOffset
                if idx >= 0:
                    points[idx] = [lastShow, point]
            self.response.out.write( sv.showSuccSO( points, strings ) )
        
        self.response.out.write( self.changeTimeLinks(action) )
